package info.rflow.util;

import info.rflow.Utils;

import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author Holger Brandl
 */
public class RRunner {


    public static String evalRComand(String cmd) {
        String[] getPckgsCmd = new String[]{getRExecutable(), "--vanilla", "--quiet", "-e", cmd};
        return evalRInternal(getPckgsCmd).getOutput();
    }


    private static StreamGobbler evalRInternal(String[] getPckgsCmd) {

        try {
//        String osName = System.getProperty("os.name" );
//        String[] cmd = new String[3];
//        if( osName.equals( "Windows NT" ) )
//        {
//            cmd[0] = "cmd.exe" ;
//            cmd[1] = "/C" ;
//            cmd[2] = args[0];
//        }

            Process proc = Runtime.getRuntime().exec(getPckgsCmd);
            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");

            // kick them off
            errorGobbler.start();
            outputGobbler.start();

            // any error???
            int exitVal = proc.waitFor();
            return outputGobbler;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }
    }


    private static String getRExecutable() {
        if (!Utils.isWindowsPlatform())
            return "R";

        // handle the more complicated case the the user's using windows
        File rHome = new File(System.getenv("R_HOME"));
        if (rHome == null) {
            rHome = new File(System.getenv("ProgramFiles") + File.separatorChar + "R");
        }
        if (rHome.isDirectory()) {
            List<File> rInstallations = Arrays.asList(rHome.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    Matcher matcher = Pattern.compile("R-([0-9.]*)").matcher(name);
                    matcher.find();
                    return matcher.matches();
                }
            }));

            File latestR = Collections.max(rInstallations, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    int v1 = Integer.parseInt(o1.getName().replace("R-", "").replaceAll("[.]", ""));
                    int v2 = Integer.parseInt(o2.getName().replace("R-", "").replaceAll("[.]", ""));

                    return v1 - v2;  //To change body of implemented methods use File | Settings | File Templates.
                }
            });

            return latestR.getAbsolutePath() + File.separatorChar + "bin" + File.separatorChar + "R.exe";
        }

        return null;
    }

}


class StreamGobbler extends Thread {

    InputStream is;
    String type;
    StringBuilder sb = new StringBuilder();


    StreamGobbler(InputStream is, String type) {
        this.is = is;
        this.type = type;
    }


    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
//                System.out.println(type + ">" + line);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }


    public String getOutput() {
        return sb.toString();
    }
}
